package com.findyou.proxy;

import com.findyou.service.AccountService;
import com.findyou.service.impl.AccountServiceImpl;
import com.findyou.utils.TransactionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @Title: JdkProxyFactory
 * @Author 贾金博
 * @Package com.findyou.proxy
 * @Date 2024/11/29 上午8:23
 * @description: JDK的工厂类
 */
@Component
public class JdkProxyFactory {

    @Autowired
    private TransactionManager transactionManager;

    @Autowired
    private AccountService accountService;

    /**
     * 采用JDK动态代理技术 生成目标对象的代理对象 是基于接口的 返回的是代理对象
     * ClassLoader loader 类加载器 借助被代理对象获取类加载
     * CLass<?>interfaces 被代理类所需要的全部接口
     * InvocationHandler 当代理对象调用任意方法的时候，执行的是invoke方法
     * @return
     */
    public AccountService createAccountServiceJdkProxy() {

        // 代理对象
        AccountService accountServiceProxy = (AccountService)Proxy.newProxyInstance(accountService.getClass().getClassLoader(), accountService.getClass().getInterfaces(), new InvocationHandler() {

            /**
             *
             * @param proxy 当前的代理对象引用
             * @param method 被调用的目标方法的引用
             * @param args 被调用的目标方法所用的参数
             * @return
             * @throws Throwable
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object result = null;
                // 开启事务
                try {
                    transactionManager.beginTransaction(); // 开启事务为手动的

                    // 业务的执行 让被代理对象的原方法执行
                   result = method.invoke(accountService, args);

                    transactionManager.commit(); // 提交事务
                } catch (Exception e) {
                    e.printStackTrace(); // 打印错误
                    // 回滚
                    transactionManager.rollback();
                } finally {
                    // 释放资源
                    transactionManager.release();
                }
                return result;
            }
        });

        return  accountServiceProxy;
    }
}
